#include <config.h>
#include "llvm-runtime.h"

#include <glib.h>
#include <mono/utils/mono-logger-internals.h>

#include <mono/metadata/mono-debug.h>
#include <mono/metadata/profiler.h>
#include "trace.h"

#ifdef HOST_WASM
#include <emscripten.h>
#endif

extern "C" {

	extern void mono_wasm_print_stack_trace (void);

// Only called by C functions or LLVM IR generated by Mono cross compiler.
// 'mono_llvm_cpp_throw_exception': function assumed not to throw an exception but does. The function is extern "C" and /EHc was specified.
MONO_DISABLE_WARNING(4297)

void
mono_llvm_cpp_throw_exception (void)
{
	gint32 *ex = NULL;

	if (mono_trace_is_enabled ())
		mono_runtime_printf_err ("Native Stacktrace (mono_llvm_cpp_throw_exception)\n");

	/* The generated code catches an int32* */
	throw ex;
}

MONO_RESTORE_WARNING

#ifdef HOST_WASM
EMSCRIPTEN_KEEPALIVE
#endif

void
mono_llvm_cpp_catch_exception (MonoLLVMInvokeCallback cb, gpointer arg, gboolean *out_thrown)
{
	*out_thrown = FALSE;
	try {
		cb (arg);
	} catch (int*) {
		*out_thrown = TRUE;
	}
}

#ifdef HOST_WASM

// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
void *__cxa_begin_catch (void *exceptionObject);
void __cxa_end_catch (void);

EMSCRIPTEN_KEEPALIVE void
mono_jiterp_begin_catch (void *exception_object) {
	__cxa_begin_catch (exception_object);
}

EMSCRIPTEN_KEEPALIVE void
mono_jiterp_end_catch (void) {
	return __cxa_end_catch ();
}

#endif

}
